﻿@page "/DataGrid"
@using System.Diagnostics.CodeAnalysis
@using System.Drawing;
@using System.Reflection

@inject IJSRuntime jsRuntime

<style>
    .table-cell-edited {
        position: relative;
    }

        .table-cell-edited::after {
            content: "";
            position: absolute;
            top: 0;
            right: 0;
            width: 0;
            height: 0;
            border-top: 10px solid red;
            border-left: 10px solid transparent;
        }

    .my-class td {
        border-top: 1px solid black;
        border-bottom: 1px solid black;
    }

</style>
<link rel="stylesheet" href="_content/Radzen.Blazor/css/material-base.css">
<link rel="stylesheet" href="_content/Radzen.Blazor/css/standard-base.css">
@* <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css"> *@
<script src="_content/Radzen.Blazor/Radzen.Blazor.js?v=@(typeof(Radzen.Colors).Assembly.GetName().Version)"></script>
<h2>DataGrid</h2>

<RadzenDataGrid EditMode="@editMode" @ref=grid TItem="PoiDto" AllowPaging="false" PageSize="5" AllowSorting="false"
                Data="@poiData" RowUpdate="@OnUpdateRow" Sort="@(args => Reset())" Page="@(args => Reset())" Filter="@(args => Reset())"
                ColumnWidth="200px" RowRender="@RowRender" AllowColumnResize="true" ValueChanged="ValueChanged">
    <Columns>
        <RadzenDataGridColumn TItem="PoiDto" Property=@nameof(PoiDto.Name) Title=@nameof(PoiDto.Name) Width="120px" IsInEditMode="@IsEditing">
            <Template Context="data">
                <RadzenText Text="@(data.Name)" />
            </Template>
            <EditTemplate Context="data">
                <RadzenTextBox @bind-Value="data.Name" Style="width:120px; display: block" Name=@nameof(PoiDto.Name) />
            </EditTemplate>
        </RadzenDataGridColumn>

        <RadzenDataGridColumn Width="40px" TItem="PoiDto" Property=@nameof(PoiDto.Show) Title=@nameof(PoiDto.Show) IsInEditMode="@IsEditing">
            <Template Context="data">
                <RadzenCheckBox Value="@data.Show" Name="Show" />
            </Template>
            <EditTemplate Context="data">
                <RadzenCheckBox @bind-Value=data.Show Name="Show" />
            </EditTemplate>
        </RadzenDataGridColumn>

        <RadzenDataGridColumn TItem="PoiDto" Property=@nameof(PoiDto.AnalysisType) Title=@nameof(PoiDto.AnalysisType) Width="120px" IsInEditMode="@IsEditing">
            <Template Context="data">
                <RadzenText Text="@(data.AnalysisType.ToString())" />
            </Template>
            <EditTemplate Context="data">
                <RadzenDropDown @bind-Value=data.AnalysisType Data="@analysisTypeDropDownLists" TextProperty=@nameof(AnalysisTypeDropDownDto.Name) ValueProperty=@nameof(AnalysisTypeDropDownDto.Value) Style="width:100%; display: block;" />
            </EditTemplate>
        </RadzenDataGridColumn>

        <RadzenDataGridColumn TItem="PoiDto" Property=@nameof(PoiDto.Range) Title=@nameof(PoiDto.Range) IsInEditMode="@IsEditing">
            <Template Context="data">
                <RadzenText Text="@(data.Range.ToString())" />
            </Template>
            <EditTemplate Context="data">
                <RadzenNumeric @bind-Value=data.Range Style="width:100%" InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "Select freight" }})" />
            </EditTemplate>
        </RadzenDataGridColumn>

        <RadzenDataGridColumn TItem="PoiDto" Property=@nameof(PoiDto.BaseLine) Title=@nameof(PoiDto.BaseLine) IsInEditMode="@IsEditing">
            <Template Context="data">
                <RadzenCheckBox Value="@data.BaseLine" Name="BaseLine" />
            </Template>
            <EditTemplate Context="data">
                <RadzenCheckBox @bind-Value=data.BaseLine Name="BaseLine" />
            </EditTemplate>
        </RadzenDataGridColumn>

        <RadzenDataGridColumn TItem="PoiDto" Property=@nameof(PoiDto.Offset) Title=@nameof(PoiDto.Offset) IsInEditMode="@IsEditing">
            <Template Context="data">
                <RadzenText Text="@(data.Offset.ToString())" />
            </Template>
            <EditTemplate Context="data">
                <RadzenNumeric @bind-Value="data.Offset" Style="width:100%" InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "Select freight" }})" />
            </EditTemplate>
        </RadzenDataGridColumn>

        <RadzenDataGridColumn Width="80px" TItem="PoiDto" Filterable="false" Sortable="false" TextAlign="Radzen.TextAlign.Center" Frozen="true" FrozenPosition="FrozenColumnPosition.Right">
            <Template Context="data">
                <RadzenButton Icon="edit" ButtonStyle="Radzen.ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@(args => EditRow(data))" @onclick:stopPropagation="true">
                </RadzenButton>
                <RadzenButton ButtonStyle="Radzen.ButtonStyle.Danger" Icon="delete" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@(args => DeleteRow(data))" @onclick:stopPropagation="true">
                </RadzenButton>
            </Template>
            <EditTemplate Context="data">
                <RadzenButton Icon="check" ButtonStyle="Radzen.ButtonStyle.Success" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@((args) => SaveRow(data))" aria-label="Save">
                </RadzenButton>
                <RadzenButton Icon="close" ButtonStyle="Radzen.ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@((args) => CancelEdit(data))" aria-label="Cancel">
                </RadzenButton>
                <RadzenButton ButtonStyle="Radzen.ButtonStyle.Danger" Icon="delete" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.Medium" class="my-1 ms-1" Click="@(args => DeleteRow(data))" aria-label="Delete">
                </RadzenButton>
            </EditTemplate>
        </RadzenDataGridColumn>

    </Columns>
</RadzenDataGrid>

<Button Text="Add" OnClick="AddRowClick" />
<Button Text="Clear" OnClick="ClearClick" />

@code {
    DataGridEditMode editMode = DataGridEditMode.Single;
    public RadzenDataGrid<PoiDto> grid;
    public string columnEditing;

    public List<PoiDto> poiData = new List<PoiDto>();
    public List<AnalysisTypeDropDownDto> analysisTypeDropDownLists = new List<AnalysisTypeDropDownDto>();

    List<KeyValuePair<int, string>> editedFields = new List<KeyValuePair<int, string>>();
    List<PoiDto> ordersToUpdate = new List<PoiDto>();

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();

        foreach (MeasureStructureValueAnalysisType value in Enum.GetValues(typeof(MeasureStructureValueAnalysisType)))
        {
            analysisTypeDropDownLists.Add(new AnalysisTypeDropDownDto
                {
                    Name = value.ToString(),
                    Value = value,
                });

        }


        poiData = new List<PoiDto>()
        {
            new PoiDto
            {
                Index=1,
               AnalysisType=  0,
                Name="Top",
                 Offset=10,
                  Range=11,
                   Show=true,
            },
        };
    }

    private void ValueChanged(IList<PoiDto> data)
    {

    }

    public bool IsEditing(string columnName, PoiDto data)
    {
        return columnEditing == columnName && ordersToUpdate.Contains(data);
    }

    public int Option { get; set; } = 1;

    public void OnCellClick(DataGridCellMouseEventArgs<PoiDto> args)
    {
        columnEditing = args.Column.Property;
        if (columnEditing != nameof(PoiDto.Show))
            return;
        if (ordersToUpdate.Any())
        {
            editedFields.Add(new(ordersToUpdate.First().Index, columnEditing));
        }


        if (ordersToUpdate.Any())
        {
            OnUpdateRow(ordersToUpdate.First());
        }
        EditRow(args.Data);
    }

    public void Reset(PoiDto data = null)
    {
        if (data != null)
        {
            ordersToUpdate.Remove(data);
        }
        else
        {
            ordersToUpdate.Clear();
        }
    }

    public async Task EditRow(PoiDto data)
    {
        Reset();

        ordersToUpdate.Add(data);
        await grid.EditRow(data);
    }

    public void OnUpdateRow(PoiDto data)
    {
        Reset(data);
    }

    public async Task DeleteRow(PoiDto data)
    {
        Reset(data);
        if (poiData.Contains(data))
        {
            poiData.Remove(data);
            await grid.Reload();
        }
        else
        {
            grid.CancelEditRow(data);
            await grid.Reload();
        }
    }

    public async Task AddRowClick()
    {
        poiData.Add(new PoiDto
            {
                Index = 2,
                Guid = Guid.NewGuid().ToString(),
                AnalysisType = 0,
                Name = "Bttom",
                Offset = 10,
                Range = 11,
                Show = true,
            });
        grid.Reload();
    }

    public async Task ClearClick()
    {
        poiData = new List<PoiDto>();
    }


    async Task SaveRow(PoiDto order)
    {
        await grid.UpdateRow(order);
        var poiOtherData = poiData.FindAll(s => !s.Equals(order)).ToList();
        poiOtherData.ForEach(s => s.BaseLine = !order.BaseLine);
    }

    void CancelEdit(PoiDto order)
    {
        Reset(order);

        grid.CancelEditRow(order);
    }

    PoiDto draggedPoiItem;

    void RowRender(RowRenderEventArgs<PoiDto> args)
    {
        args.Attributes.Add("title", "Drag row to reorder");
        args.Attributes.Add("style", "cursor:grab");
        args.Attributes.Add("draggable", "true");
        args.Attributes.Add("ondragover", "event.preventDefault();event.target.closest('.rz-data-row').classList.add('my-class')");
        args.Attributes.Add("ondragleave", "event.target.closest('.rz-data-row').classList.remove('my-class')");
        args.Attributes.Add("ondragstart", EventCallback.Factory.Create<DragEventArgs>(this, () => draggedPoiItem = args.Data));
        args.Attributes.Add("ondrop", EventCallback.Factory.Create<DragEventArgs>(this, async () =>
        {
            var draggedIndex = poiData.IndexOf(draggedPoiItem);
            var droppedIndex = poiData.IndexOf(args.Data);
            poiData.Remove(draggedPoiItem);
            poiData.Insert(draggedIndex <= droppedIndex ? droppedIndex++ : droppedIndex, draggedPoiItem);

            jsRuntime.InvokeVoidAsync("eval", $"document.querySelector('.my-class').classList.remove('my-class')");
            await grid.Reload();
        }));
    }

    public class PoiDto
    {
        public int Index { get; set; }

        public string Guid { get; set; }

        public string Name { get; set; }

        public bool Show { get; set; }

        public double Offset { get; set; }

        public double Range { get; set; }

        public MeasureStructureValueAnalysisType AnalysisType { get; set; }

        public bool BaseLine { get; set; }
    }

    public class AnalysisTypeDropDownDto
    {
        public MeasureStructureValueAnalysisType Value { get; set; }
        public string Name { get; set; }
    }

    public enum MeasureStructureValueAnalysisType
    {
        //平均值
        Mean = 0,
        //最大值
        Max = 1,
        //最小值
        Min = 2
    }

}
